<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace addons\database_manage\controller;

use  addons\database_manage\service\DatabaseService;
use think\facade\View;
use think\facade\Session;

/**
 * Copyright
 */
class Index extends PluginBaseController
{
    protected $noNeedLogin = ['import'];
    protected $noNeedRight = ['import'];

    use \buwang\traits\Crud;
    protected $relationSearch = true;
    protected $DB;

    /**
     * 安装日志文件名称
     * @var string
     */
    protected $install_log_file_name = 'database_backup/import.log';
    protected $install_flag = 'database_backup/flag.log';


    public function initialize()
    {
        parent::initialize();
        $this->DB = new DatabaseService([]);
    }


    /**
     * @NodeAnotation(title="列表")
     */
    public function index()
    {
        if ($this->request->isAjax()) {
            if (input('selectFieds')) {
                return $this->selectList();
            }
            list($page, $limit, $where) = $this->buildTableParames();

            $data = [
                'total' => count($this->DB->dataList()),
                'list' => $this->DB->dataList(),
            ];
            return $this->success('success', $data);
        }
        return $this->fetch();
    }

    /**
     * @NodeAnotation(title="表详情")
     */
    public function detail()
    {
        $tablename = $this->request->get('table_name');
        $list = $this->DB->tableDetail($tablename);
        return $this->fetch('', ['list' => $list,'count'=>count($list)]);
    }

    /**
     * @NodeAnotation(title="备份")
     */
    public function backup()
    {
        $tables = $this->request->post('tables/s');//得到要备份的表
        $tables = explode(",", $tables);
        $db = $this->DB;
        $data = '';

        foreach ($tables as $t) {
            $res = $db->backup($t, 0);
            if ($res == false && $res != 0) {
                $data .= $t . '|';
            }
        }
        return $this->success($data ? '备份失败' . $data : '备份成功');
    }


    /**@NodeAnotation(title="获取备份记录表")
     */
    public function backupList()
    {
        if ($this->request->isAjax()) {
            if (input('selectFieds')) {
                return $this->selectList();
            }
            list($page, $limit, $where) = $this->buildTableParames();

            $db = $this->DB;
            $files = $db->fileList();//得到文件列表
            $data = [];
            foreach ($files as $key => $t) {   //创建时间 => 备份信息
                $data[$key]['filename'] = $t['filename'];
                $data[$key]['part'] = $t['part'];  //备份分组数
                $data[$key]['size'] = DatabaseService::dataFormat($t['size']); //备份文件大小
                $data[$key]['compress'] = $t['compress']; //压缩格式
                $data[$key]['backtime'] = $key;  //备份时间
                $data[$key]['time'] = $t['time']; //备份时间
            }
            krsort($data);//根据时间降序
            $list = $db->page_list($page, $limit, $data);//数组分页
            $data = [
                'total' => $list['total'],
                'list' => $list['list'],
            ];
            return $this->success('success', $data);
        }
        return $this->fetch();
    }


    /**
     * @NodeAnotation(title="备份导入")
     */
    public function import()
    {
        $time = intval($this->request->get('time'));
        $part = 1;
        $db = $this->DB;
        //如果存在时间和卷数
        if (is_numeric($time) && is_numeric($part)) {
            file_put_contents($this->install_flag, 'lock');
            file_put_contents($this->install_log_file_name, '');
            file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '检测-备份文件' . PHP_EOL, FILE_APPEND);
            $list = $db->getFile('timeverif', $time);//得到对应的备份文件信息
            if (!is_array($list)) {
                file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份文件可能已经损坏，请检查！' . PHP_EOL, FILE_APPEND);
                return $this->error('备份文件可能已经损坏，请检查！');
            }
            file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份文件卷1开始数据覆盖！' . PHP_EOL, FILE_APPEND);
            $start = [0, 0];//读取并执行第一卷的备份sql语句
            while (is_array($start)) {
                file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . "备份文件卷1已覆盖：{$start[0]}B" . PHP_EOL, FILE_APPEND);//写日志
                $start = $db->setFile($list)->import($start[0]);//读取并执行第一卷的备份sql语句
            }
            file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份文件卷1覆盖完成' . PHP_EOL, FILE_APPEND);
            if (false === $start) {
                file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份文件卷1还原数据出错！' . PHP_EOL, FILE_APPEND);
                return $this->error('卷1还原数据出错！');
            } elseif (0 === $start) {
                //只有一卷则以还原完
                if (!isset($list[++$part])) {
                    file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份覆盖全部完成' . PHP_EOL, FILE_APPEND);
                    @unlink($this->install_flag);
                    return $this->success('还原完成！');
                } else {
                    //还有其他卷
                    foreach ($list as $file) {
                        if ($file[0] != 1) {
                            $start = [0, 0];//读取并执行第一卷的备份sql语句
                            while (is_array($start)) {
                                file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . "备份文件卷{$file[0]}已覆盖：{$start[0]}B" . PHP_EOL, FILE_APPEND);//写日志
                                $start = $db->setFile($file, true)->import($start[0]);//读取并执行第一卷的备份sql语句
                            }
                            file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . "备份文件卷{$file[0]}覆盖完成" . PHP_EOL, FILE_APPEND);
                            if (false === $start) return $this->error("卷{$file[0]}还原数据出错");
                        }
                    }
                    file_put_contents($this->install_log_file_name, date('Y-m-d H:i:s', time()) . '-' . '备份覆盖全部完成' . PHP_EOL, FILE_APPEND);
                    @unlink($this->install_flag);
                    return $this->success('还原完成！');
                }
            }
        } else {
            return $this->error('参数错误！');
        }

    }


    /**
     * @NodeAnotation(title="备份删除")
     */
    public function del()
    {
        $time = intval($this->request->get('time'));
        $this->DB->delFile($time);
        return $this->success('删除成功！');
    }

    /**
     * @NodeAnotation(title="备份下载")
     */
    public function download()
    {
        $time = intval($this->request->get('time'));
        $this->DB->downloadFile($time);
    }

    /**
     * @NodeAnotation(title="表优化")
     */
    public function optimize()
    {
        $tables = $this->request->post('tables/s');//得到要备份的表
        $tables = explode(",", $tables);
        $db = $this->DB;
        $res = $db->optimize($tables);
        return $this->success($res ? '优化成功' : '优化失败');
    }


    /**
     * @NodeAnotation(title="表修复")
     */
    public function repair()
    {
        $tables = $this->request->post('tables/s');//得到要备份的表
        $tables = explode(",", $tables);
        $db = $this->DB;
        $res = $db->repair($tables);
        return $this->success($res ? '修复成功' : '修复失败');
    }

    public function process()
    {
        if (request()->isGet()) {
            return $this->fetch();
        }
        if (request()->isPost()) {
            if (file_exists($this->install_flag)) {
                $info = file_get_contents($this->install_log_file_name);
                $arr = explode(PHP_EOL, $info);
                return $this->success('安装进行中', $arr);
            } else {
                return $this->error('安装成功');
            }
        }
    }


    public function _empty($param)
    {
        var_dump("不存在方法：" . $param);
    }

}